perf: efficient IPC layer, bundle split, monaco workers offload#28
perf: efficient IPC layer, bundle split, monaco workers offload#28remcostoeten merged 11 commits intomasterfrom
Conversation
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds a GitHub Actions release workflow, refactors desktop app UI (many component removals), introduces Monaco worker initialization, replaces theme "haptic" with "night", adds optimistic updates for table cell mutations, injects a deps indirection for Tauri shell in docker client, and adds multiple developer tooling scripts and dependency updates. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as Client (UI)
participant Mutation as useMutation (updateCell)
participant Cache as React Query Cache
participant API as Backend API
UI->>Mutation: call updateCell(newValue)
activate Mutation
Mutation->>Cache: onMutate — snapshot previous tableData
Mutation->>Cache: apply optimistic update to tableData
Cache-->>UI: render optimistic state
par network
Mutation->>API: send mutation request
alt success
API-->>Mutation: success response
Mutation->>Cache: onSettled — invalidate tableData
Cache->>API: refetch tableData
API-->>Cache: new data
Cache-->>UI: render confirmed state
else error
API-->>Mutation: error
Mutation->>Cache: onError — restore snapshot
Cache-->>UI: revert to previous state
end
end
deactivate Mutation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Sorry @remcostoeten, your pull request is larger than the review limit of 150000 diff characters
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
apps/desktop/src-tauri/src/database/commands.rs (1)
244-255: Type annotation mismatch between backend and frontend bindings forfetch_page.The backend correctly returns
Option<Box<serde_json::value::RawValue>>for efficient IPC pass-through. However, the auto-generated frontend type annotation declares the return asJsonValue | null, which is incompatible.RawValueserializes as raw JSON text, not as a parsedJsonValueobject. The frontend bindings appear out of sync with the Rust type changes—regenerate bindings usingtauri-spectato correct the TypeScript type annotation, or update it manually to reflect that the actual return value is a raw JSON string representation.__tests__/apps/desktop/src/features/docker-manager/api/docker-client.test.ts (1)
11-49: Replaceanywith explicit Vitest mock types.Using
anyerodes type safety. Per coding guidelines, prefer explicit types overany. For Vitest 4, useMock<FunctionType>from vitest instead ofReturnType<typeof vi.fn>:♻️ Suggested typing cleanup
+ import { type Mock } from 'vitest' + - let mockExecute: any - let mockCreate: any + let mockExecute: Mock<() => Promise<{ stdout: string; stderr: string; code: number }>> + let mockCreate: Mock<(cmd: string, args: string[]) => void> beforeEach(() => { vi.clearAllMocks() mockExecute = vi.fn().mockResolvedValue({ stdout: '', stderr: '', code: 0 }) mockCreate = vi.fn() // Inject mock - deps.getCommand = async () => ({ + type CommandCtor = typeof import('@tauri-apps/plugin-shell').Command + deps.getCommand = async () => + ({ create: (cmd: string, args: string[]) => { mockCreate(cmd, args) return { execute: mockExecute, on: vi.fn(), spawn: vi.fn().mockResolvedValue({ kill: vi.fn() }), stdout: { on: vi.fn() }, stderr: { on: vi.fn() } } } - } as any) + } as unknown as CommandCtor)apps/desktop/src/shared/lib/appearance-store.ts (1)
23-56: Migrate legacyhaptictheme tonight.If localStorage still contains
haptic, the old class persists and the UI may lose theme styling. Maphaptic→nighton load and remove the legacy class from the DOM.🔧 Proposed fix
export function getAppearanceSettings(): AppearanceSettings { try { const stored = localStorage.getItem(STORAGE_KEY) if (stored) { // Merge with defaults to handle removal of density or new fields const parsed = JSON.parse(stored) + if (parsed.theme === 'haptic') parsed.theme = 'night' // Remove legacy density if present delete parsed.density return { ...DEFAULT_SETTINGS, ...parsed } } } catch (e) { console.warn('Failed to load appearance settings:', e) } return DEFAULT_SETTINGS } @@ // Theme - root.classList.remove('light', 'dark', 'midnight', 'forest', 'claude', 'claude-dark', 'night') + root.classList.remove('light', 'dark', 'midnight', 'forest', 'claude', 'claude-dark', 'night', 'haptic') root.classList.add(settings.theme)
🤖 Fix all issues with AI agents
In @.github/workflows/release.yml:
- Around line 69-70: The workflow step "install rust stable" currently uses an
invalid action reference "dtolnay/rust-action@stable"; update this step's uses
value to the correct, valid action reference consistent with the Linux job fix
(replace the "uses: dtolnay/rust-action@stable" entry with the same working
reference used in the other job), ensuring the step name "install rust stable"
and the uses entry are updated together so the workflow picks the valid action.
- Around line 108-109: The "install rust stable" step is using an invalid action
reference (uses: dtolnay/rust-action@stable); update that step to use the same
correct action reference used in the Linux job (replace the
dtolnay/rust-action@stable value with the validated action identifier used
elsewhere in this workflow), keeping the step name "install rust stable" and
ensuring the action version/tag matches the Linux job's working configuration.
- Around line 25-26: The workflow uses an invalid GitHub Action identifier
"dtolnay/rust-action@stable" which will fail; update the step that currently
says uses: dtolnay/rust-action@stable to use the correct action identifier uses:
dtolnay/rust-toolchain@stable so the "install rust stable" step uses the proper
dtolnay/rust-toolchain action.
- Around line 28-31: Update the Ubuntu install step "install dependencies
(ubuntu)" to use the Tauri v2-required packages: replace libwebkit2gtk-4.0-dev
with libwebkit2gtk-4.1-dev and replace libappindicator3-dev with
libayatana-appindicator3-dev in the apt-get install list so the workflow matches
Tauri v2 prerequisites.
- Around line 119-133: Add the missing APPLE_TEAM_ID environment variable to the
tauri-action@v0 step so macOS notarization can use Apple ID-based notarization;
update the env block that already contains APPLE_ID and APPLE_PASSWORD to
include APPLE_TEAM_ID (reference the tauri-action@v0 step and the env variables
APPLE_ID and APPLE_PASSWORD) so the action receives APPLE_TEAM_ID from secrets
for notarization.
- Around line 41-50: The workflow uses the loose tauri-action@v0 and runs
release jobs in parallel causing race conditions; update the action reference in
the step that currently says "uses: tauri-apps/tauri-action@v0" to the pinned
"tauri-apps/tauri-action@v0.6.1" and serialize the release jobs by adding job
dependencies so the Windows and macOS release jobs (e.g., job ids like
release-windows and release-macos) include "needs: release-linux" (or whatever
the Linux release job id is) so only the Linux job creates/updates the GitHub
release first.
In `@apps/desktop/src/core/data-provider/hooks.ts`:
- Line 1: Replace the use of `any` in the optimistic updater with a concrete
response type: define a `TableDataResponse` interface/type that matches the API
shape (including `rows: Array<...>` and any other fields) and then change the
`queryClient.setQueriesData` updater signature to use that type instead of `any`
(the call site is the optimistic update using `queryClient.setQueriesData({
queryKey: ['tableData', newEdit.connectionId, newEdit.tableName] }, (old: any)
=> { ... })`); ensure the updater handles `old` possibly being undefined (narrow
or default it) and update usages inside the updater to rely on the typed
`old.rows` so TypeScript enforces correctness.
In `@apps/desktop/src/features/drizzle-runner/components/lsp-demo-widget.tsx`:
- Around line 238-252: The auto-close effect handleSuccessAutoClose should only
perform the 2s auto-close and countdown when an onClose callback is provided;
update the useEffect so it checks that isSuccess && typeof onClose ===
"function" before setting the timer, and only call onClose and clear/set
IsSuccess inside that guarded branch (keep the cleanup to clear timer). Apply
the same guard to the other similar effect/logic that shows the "Closing in 2
seconds..." countdown and auto-clears success (the second effect around the
countdown), ensuring the message is only shown when onClose exists.
- Around line 115-117: The declared state setter setDemos is unused and triggers
eslint no-unused-vars; either remove the setter from the useState call or rename
it to _setDemos to silence the linter. Update the hook declaration that
currently reads useState<DemoQuery[]>(DEFAULT_DEMOS) so it only keeps the needed
symbols (e.g., keep demos and remove setDemos) or rename setDemos to _setDemos;
make this change where demos, setDemos, DEFAULT_DEMOS and useState are
referenced so future edits can restore the setter if needed.
In `@tools/scan-dependencies.ts`:
- Line 14: The arrow function readFile should be converted to a function
declaration to satisfy ESLint; replace the const readFile = (p: string) => ...
with a function declaration function readFile(p: string): string { ... }
preserving the exact behavior (check fs.existsSync(p) and return
fs.readFileSync(p, 'utf-8') or ''), keeping the same function name and parameter
to avoid changing callers.
🧹 Nitpick comments (15)
__tests__/apps/desktop/features/drizzle-runner/lsp-patterns.test.ts (1)
14-14: Consider using a path alias instead of a deep relative import.The 6-level relative path (
../../../../../) is brittle and makes the test fragile to directory structure changes. Using a path alias would improve maintainability.♻️ Suggested refactor using path alias
-} from '../../../../../apps/desktop/src/features/drizzle-runner/utils/lsp-patterns' +} from '@/apps/desktop/src/features/drizzle-runner/utils/lsp-patterns'Note: Ensure your tsconfig paths or vitest config includes an alias mapping for
@/pointing to the project root or appropriate base path..github/workflows/release.yml (1)
7-51: Consider adding dependency caching for faster CI builds.The workflow installs Bun packages and Rust dependencies from scratch on every run. Adding caching can significantly reduce build times.
♻️ Example cache configuration for the Linux job
- name: setup bun uses: oven-sh/setup-bun@v2 with: bun-version: latest + - name: cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + apps/desktop/src-tauri/target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - name: install rust stable uses: dtolnay/rust-toolchain@stableapps/desktop/src/features/drizzle-runner/components/lsp-demo-widget.tsx (1)
340-366: Prefer shared Button component and explicit props typing.This inline Button duplicates the shared UI primitive and uses
any. Consider importing the sharedButtonfrom@/shared/components/uiand extending its variants (e.g., addingsuccess) there. This keeps styling consistent and aligns with the TS typing guideline. As per coding guidelines, prefer shared UI primitives and avoidany.apps/desktop/src/core/data-provider/hooks.ts (1)
192-204: Use the existingTableDatatype instead ofany.The codebase already defines a
TableDatatype in@/features/database-studio/types.tswith the structure{ columns: ColumnDefinition[], rows: Record<string, unknown>[], totalCount: number, executionTime: number }. Import and use this type for the optimistic update instead ofany.♻️ Suggested typing update
+import type { TableData } from '@/features/database-studio/types' + - queryClient.setQueriesData({ queryKey: ['tableData', newEdit.connectionId, newEdit.tableName] }, (old: any) => { + queryClient.setQueriesData<TableData>( + { queryKey: ['tableData', newEdit.connectionId, newEdit.tableName] }, + (old) => { - if (!old) return old + if (!old?.rows) return old - return { - ...old, - rows: old.rows.map((row: any) => { + return { + ...old, + rows: old.rows.map((row) => { - if (row[newEdit.primaryKeyColumn] === newEdit.primaryKeyValue) { - return { - ...row, - [newEdit.columnName]: newEdit.newValue - } - } - return row - }) - } - }) + if (row[newEdit.primaryKeyColumn] === newEdit.primaryKeyValue) { + return { + ...row, + [newEdit.columnName]: newEdit.newValue + } + } + return row + }) + } + } + )package.json (1)
46-47: Consider pinning React versions consistently.
reactandreact-domare pinned at18.3.1without the^prefix, which is good for deterministic builds. Ensure these versions match what's used inapps/desktop/package.jsonto avoid version mismatches in the monorepo.tools/clean-fix.sh (2)
4-5: Consider using script directory instead ofpwd.Using
pwdmakes the script dependent on the caller's working directory. Deriving the root from the script's location is more robust.Suggested improvement
-# Define root directory -ROOT_DIR=$(pwd) +# Define root directory relative to script location +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12-13: Add existence checks for safety.If
appsorpackagesdirectories don't exist,findwill error. Consider adding guards or using-maxdepth 0checks.Suggested improvement
# Find and remove items in subdirectories -find "$ROOT_DIR/apps" "$ROOT_DIR/packages" -type d \( -name "node_modules" -o -name ".next" -o -name ".turbo" -o -name "dist" -o -name ".vite" \) -prune -exec rm -rf {} + +for dir in "$ROOT_DIR/apps" "$ROOT_DIR/packages"; do + if [ -d "$dir" ]; then + find "$dir" -type d \( -name "node_modules" -o -name ".next" -o -name ".turbo" -o -name "dist" -o -name ".vite" \) -prune -exec rm -rf {} + + fi +doneapps/desktop/src/features/sidebar/components/bottom-toolbar.tsx (1)
1-13: Avoid Theme type drift by importing the shared Theme type.
Themealready exists inapps/desktop/src/shared/lib/appearance-store.ts; reusing it prevents future mismatches.♻️ Suggested change
import { Settings, Monitor, Sparkles, Info } from 'lucide-react' +import type { Theme } from '@/shared/lib/appearance-store' @@ -type Theme = 'dark' | 'light' | 'midnight' | 'forest' | 'claude' | 'claude-dark' | 'night'__tests__/apps/desktop/src/features/docker-manager/api/container-service.test.ts (1)
13-16: Avoidanyfor dynamically imported modules.Use
typeof import(...)to keep the module API typed and refactor-safe.🔧 Proposed fix
- let containerService: any; - let dockerClient: any; + type DockerClientModule = typeof import('../../../../../../../apps/desktop/src/features/docker-manager/api/docker-client') + type ContainerServiceModule = typeof import('../../../../../../../apps/desktop/src/features/docker-manager/api/container-service') + let containerService: ContainerServiceModule; + let dockerClient: DockerClientModule;As per coding guidelines, prefer explicit types over
any.__tests__/apps/desktop/src/features/docker-manager/components/docker-view.test.tsx (1)
6-6: Use the shared UI index for TooltipProvider.Shared UI primitives should be imported from
@/shared/components/ui; update the TooltipProvider import accordingly (or re-export it there).🔧 Proposed fix
-import { TooltipProvider } from '@/shared/ui/tooltip' +import { TooltipProvider } from '@/shared/components/ui'As per coding guidelines, import shared UI primitives from
@/shared/components/ui.tools/audit-cleanup.sh (1)
7-9: AnchorPROJECT_ROOTto the script location.Using
pwdmakes behavior depend on the caller’s CWD; in execute mode this can delete the wrong paths or runbun run buildoutside the repo. Resolve the repo root relative to the script instead.🔧 Proposed fix
-BACKUP_ROOT="$HOME/.dora/backups/$(date +%Y%m%d_%H%M%S)" -PROJECT_ROOT=$(pwd) +BACKUP_ROOT="$HOME/.dora/backups/$(date +%Y%m%d_%H%M%S)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"tools/scan-dependencies.ts (1)
77-103: Substring matching may yield false positives for short package names.The heuristic
allContent.includes(dep)can match unrelated occurrences. For example,iswould match any word containing "is". Consider using a regex with word boundaries for more accurate detection, especially for short package names.Suggested improvement
- const isUsed = allContent.includes(dep) || (isTypes && allContent.includes(searchName)); + // Use word boundary check for more accurate matching + const depPattern = new RegExp(`['"\`/]${dep.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}['"\`/]|from\\s+['"]${dep.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`) + const searchPattern = isTypes ? new RegExp(`['"\`]${searchName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}['"\`]`) : null + const isUsed = depPattern.test(allContent) || (isTypes && searchPattern?.test(allContent));recap.md (1)
8-12: Minor: Consider varying sentence structure.Three consecutive bullet points start with "Tried". Consider rephrasing for better readability (e.g., "Added debug logs...", "Experimented with...", "Created a global...").
apps/desktop/src/features/sidebar/database-sidebar.tsx (1)
681-689: Consider adding keyboard accessibility for the resizer.The resizer handle only responds to mouse events. For accessibility, consider adding keyboard support (e.g., arrow keys to adjust the ratio when focused).
Example keyboard support
<div + tabIndex={0} + role="separator" + aria-orientation="horizontal" + aria-valuenow={Math.round(topPanelRatio * 100)} className='h-1.5 shrink-0 bg-sidebar-border/30 hover:bg-primary/20 cursor-row-resize flex items-center justify-center transition-colors z-20 -my-0.5' onMouseDown={(e) => { e.preventDefault() setIsResizing(true) }} + onKeyDown={(e) => { + if (e.key === 'ArrowUp') { + setTopPanelRatio(r => Math.max(0.2, r - 0.05)) + } else if (e.key === 'ArrowDown') { + setTopPanelRatio(r => Math.min(0.85, r + 0.05)) + } + }} >apps/desktop/src/monaco-workers.ts (1)
8-24: Replaceanywith explicit type.Per coding guidelines, prefer explicit types over
any. The first parameter is the module ID (string).Proposed fix
self.MonacoEnvironment = { - getWorker(_: any, label: string) { + getWorker(_moduleId: string, label: string) { if (label === 'json') {
| - name: install dependencies (ubuntu) | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check Tauri version in Cargo.toml
fd -t f 'Cargo.toml' -x grep -H 'tauri' {} \;Repository: remcostoeten/dora
Length of output: 478
🌐 Web query:
Tauri v2 Linux dependencies libwebkit2gtk libappindicator official documentation
💡 Result:
In Tauri v2, the official docs list these Linux packages relevant to your question:
-
Development (build) dependencies (Debian/Ubuntu example):
libwebkit2gtk-4.1-dev(WebView / WebKit2GTK)libayatana-appindicator3-dev(AppIndicator/system tray support; Tauri v2 uses Ayatana on many distros) (v2.tauri.app)
-
Runtime (shipping) dependencies for Debian-based .deb packages:
libwebkit2gtk-4.1-0libgtk-3-0libappindicator3-1only if your app uses the system tray (v2.tauri.app)
If you specifically meant libappindicator vs libayatana-appindicator: Tauri v2’s prerequisites page uses Ayatana (libayatana-appindicator3-dev) for the Linux dev setup example. (v2.tauri.app)
Citations:
- 1: https://v2.tauri.app/start/prerequisites/?utm_source=openai
- 2: https://v2.tauri.app/es/distribute/debian/?utm_source=openai
- 3: https://v2.tauri.app/start/prerequisites/?utm_source=openai
Update Linux dependencies for Tauri v2.
The workflow is using Tauri v2.8.0 but has outdated dependencies. For Tauri v2, replace:
libwebkit2gtk-4.0-dev→libwebkit2gtk-4.1-devlibappindicator3-dev→libayatana-appindicator3-dev
This aligns with the official Tauri v2 prerequisites.
🤖 Prompt for AI Agents
In @.github/workflows/release.yml around lines 28 - 31, Update the Ubuntu
install step "install dependencies (ubuntu)" to use the Tauri v2-required
packages: replace libwebkit2gtk-4.0-dev with libwebkit2gtk-4.1-dev and replace
libappindicator3-dev with libayatana-appindicator3-dev in the apt-get install
list so the workflow matches Tauri v2 prerequisites.
| - uses: tauri-apps/tauri-action@v0 | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| with: | ||
| projectPath: ./apps/desktop | ||
| tagName: ${{ github.ref_name }} | ||
| releaseName: 'App v__VERSION__' | ||
| releaseBody: 'See the assets to download this version and install.' | ||
| releaseDraft: true | ||
| prerelease: false |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
latest stable version tauri-apps/tauri-action GitHub Action
💡 Result:
Latest stable release of tauri-apps/tauri-action is v0.6.1 (tag: action-v0.6.1, released 2026-01-03). [1]
You can pin it as:
- uses: tauri-apps/tauri-action@v0.6.1Source: GitHub Releases page. [1]
[1] https://github.com/tauri-apps/tauri-action/releases
🏁 Script executed:
# Let's examine the release.yml workflow to understand the job structure
cat -n .github/workflows/release.ymlRepository: remcostoeten/dora
Length of output: 4572
Pin tauri-action to v0.6.1 and serialize release jobs to prevent race conditions.
-
Using
@v0is very loose and could introduce breaking changes unexpectedly. Pin to the latest stable version:@v0.6.1. -
All three jobs run in parallel and each attempts to create/update the same GitHub release. This can cause race conditions. Consider making Windows and macOS jobs depend on the Linux job using
needs: release-linux.
♻️ Proposed fix for job dependencies
release-windows:
+ needs: release-linux
permissions:
contents: write
runs-on: windows-latest release-macos:
+ needs: release-linux
permissions:
contents: write
runs-on: macos-latest🤖 Prompt for AI Agents
In @.github/workflows/release.yml around lines 41 - 50, The workflow uses the
loose tauri-action@v0 and runs release jobs in parallel causing race conditions;
update the action reference in the step that currently says "uses:
tauri-apps/tauri-action@v0" to the pinned "tauri-apps/tauri-action@v0.6.1" and
serialize the release jobs by adding job dependencies so the Windows and macOS
release jobs (e.g., job ids like release-windows and release-macos) include
"needs: release-linux" (or whatever the Linux release job id is) so only the
Linux job creates/updates the GitHub release first.
| - uses: tauri-apps/tauri-action@v0 | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | ||
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | ||
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | ||
| APPLE_ID: ${{ secrets.APPLE_ID }} | ||
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | ||
| with: | ||
| projectPath: ./apps/desktop | ||
| tagName: ${{ github.ref_name }} | ||
| releaseName: 'App v__VERSION__' | ||
| releaseBody: 'See the assets to download this version and install.' | ||
| releaseDraft: true | ||
| prerelease: false |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
tauri-apps tauri-action v0 macOS notarization APPLE_TEAM_ID environment variables
💡 Result:
For tauri-apps/tauri-action@v0 on macOS, notarization credentials are passed via environment variables (typically from GitHub Secrets). If you notarize using Apple ID + app-specific password, you should set all of these:
APPLE_ID(your Apple ID email)APPLE_PASSWORD(app-specific password)APPLE_TEAM_ID(your Apple Developer Team ID) — required when using Apple ID auth for notarization in current tooling/docs- (for signing)
APPLE_CERTIFICATE(base64.p12),APPLE_CERTIFICATE_PASSWORD,APPLE_SIGNING_IDENTITY(keychain identity name)
Example (as used with tauri-action@v0):
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}Sources: Tauri v1 signing guide (shows tauri-action@v0 + APPLE_TEAM_ID) [1], Tauri environment variables reference (states APPLE_TEAM_ID is required when APPLE_ID is provided) [2], and tauri-bundler release notes calling out APPLE_TEAM_ID being required for Apple ID notarization auth [3].
References
[1] https://v1.tauri.app/v1/guides/distribution/sign-macos/
[2] https://v2.tauri.app/reference/environment-variables/
[3] https://v2.tauri.app/release/tauri-bundler/v1.4.1/
Add missing APPLE_TEAM_ID environment variable for macOS notarization.
The workflow is missing APPLE_TEAM_ID, which is required for Apple ID-based notarization with tauri-action@v0. Without it, notarization will fail. Add:
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}to the environment variables alongside the existing APPLE_ID and APPLE_PASSWORD.
🤖 Prompt for AI Agents
In @.github/workflows/release.yml around lines 119 - 133, Add the missing
APPLE_TEAM_ID environment variable to the tauri-action@v0 step so macOS
notarization can use Apple ID-based notarization; update the env block that
already contains APPLE_ID and APPLE_PASSWORD to include APPLE_TEAM_ID (reference
the tauri-action@v0 step and the env variables APPLE_ID and APPLE_PASSWORD) so
the action receives APPLE_TEAM_ID from secrets for notarization.
| @@ -1,4 +1,4 @@ | |||
| import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' | |||
| import { useMutation, useQuery, useQueryClient, keepPreviousData } from '@tanstack/react-query' | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check `@tanstack/react-query` version in manifests/lockfiles
rg -n '"@tanstack/react-query"' -g 'package.json' -g 'pnpm-lock.yaml' -g 'yarn.lock' -g 'package-lock.json' | head -20Repository: remcostoeten/dora
Length of output: 205
🏁 Script executed:
#!/bin/bash
# Check the actual file content for the imports and usage
cat -n apps/desktop/src/core/data-provider/hooks.ts | head -50Repository: remcostoeten/dora
Length of output: 1725
🏁 Script executed:
#!/bin/bash
# Read more of the file to see the changes around lines 141-144 and 184-224
cat -n apps/desktop/src/core/data-provider/hooks.ts | sed -n '130,250p'Repository: remcostoeten/dora
Length of output: 4158
🌐 Web query:
keepPreviousData React Query v5.83.0 API
💡 Result:
In TanStack React Query v5.83.0, there is no keepPreviousData: true option anymore. It was removed in v5 in favor of placeholderData (and the flag isPlaceholderData instead of isPreviousData). (tanstack.com)
Equivalent v5 API
Option form (identity function):
useQuery({
queryKey,
queryFn,
placeholderData: (previousData) => previousData,
})Using the built-in helper (recommended):
import { useQuery, keepPreviousData } from '@tanstack/react-query'
useQuery({
queryKey,
queryFn,
placeholderData: keepPreviousData,
})Flag replacement:
- v4
isPreviousData→ v5isPlaceholderData(tanstack.com)
Citations:
- 1: https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5?utm_source=openai
- 2: https://tanstack.com/query/v5/docs/framework/react/guides/paginated-queries?utm_source=openai
- 3: https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5?utm_source=openai
- 4: https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5?utm_source=openai
Use explicit type instead of any for the optimistic updater parameter.
The keepPreviousData import is available in React Query v5.83.0 and correctly used. However, the optimistic updater at line 192 should not use any for the cached data parameter:
queryClient.setQueriesData({ queryKey: ['tableData', newEdit.connectionId, newEdit.tableName] }, (old: TableDataResponse) => {Define TableDataResponse type to match your API response structure (with rows array) and use it instead of any to maintain type safety throughout the optimistic update.
🤖 Prompt for AI Agents
In `@apps/desktop/src/core/data-provider/hooks.ts` at line 1, Replace the use of
`any` in the optimistic updater with a concrete response type: define a
`TableDataResponse` interface/type that matches the API shape (including `rows:
Array<...>` and any other fields) and then change the
`queryClient.setQueriesData` updater signature to use that type instead of `any`
(the call site is the optimistic update using `queryClient.setQueriesData({
queryKey: ['tableData', newEdit.connectionId, newEdit.tableName] }, (old: any)
=> { ... })`); ensure the updater handles `old` possibly being undefined (narrow
or default it) and update usages inside the updater to rely on the typed
`old.rows` so TypeScript enforces correctness.
| // ... existing state ... | ||
| const [isSuccess, setIsSuccess] = useState(false) | ||
| const [demos, setDemos] = useState<DemoQuery[]>(DEFAULT_DEMOS) |
There was a problem hiding this comment.
Fix unused setDemos to clear the CI warning.
CI shows setDemos is unused (eslint no-unused-vars). Remove it or rename to _setDemos if you intend to keep it around.
🧹 Proposed fix
- const [demos, setDemos] = useState<DemoQuery[]>(DEFAULT_DEMOS)
+ const [demos] = useState<DemoQuery[]>(DEFAULT_DEMOS)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // ... existing state ... | |
| const [isSuccess, setIsSuccess] = useState(false) | |
| const [demos, setDemos] = useState<DemoQuery[]>(DEFAULT_DEMOS) | |
| // ... existing state ... | |
| const [isSuccess, setIsSuccess] = useState(false) | |
| const [demos] = useState<DemoQuery[]>(DEFAULT_DEMOS) |
🧰 Tools
🪛 GitHub Actions: CI
[warning] 117-117: eslint(no-unused-vars): Variable 'setDemos' is declared but never used. Unused variables should start with a '_'.
🤖 Prompt for AI Agents
In `@apps/desktop/src/features/drizzle-runner/components/lsp-demo-widget.tsx`
around lines 115 - 117, The declared state setter setDemos is unused and
triggers eslint no-unused-vars; either remove the setter from the useState call
or rename it to _setDemos to silence the linter. Update the hook declaration
that currently reads useState<DemoQuery[]>(DEFAULT_DEMOS) so it only keeps the
needed symbols (e.g., keep demos and remove setDemos) or rename setDemos to
_setDemos; make this change where demos, setDemos, DEFAULT_DEMOS and useState
are referenced so future edits can restore the setter if needed.
| // Auto-close on success | ||
| useEffect( | ||
| function handleSuccessAutoClose() { | ||
| if (isSuccess) { | ||
| const timer = setTimeout(function closeWidget() { | ||
| setIsSuccess(false) | ||
| if (onClose) onClose() | ||
| }, 2000) | ||
| return function cleanup() { | ||
| clearTimeout(timer) | ||
| } | ||
| } | ||
| }, | ||
| [isSuccess, onClose] | ||
| ) |
There was a problem hiding this comment.
Guard auto-close + countdown copy when onClose is absent.
Right now the “Closing in 2 seconds...” message appears even when onClose isn’t provided, and the effect still clears success after 2s. That reads like a close that never happens. Consider only auto-closing (and showing the countdown) when onClose exists.
✅ Suggested adjustment
- useEffect(
- function handleSuccessAutoClose() {
- if (isSuccess) {
- const timer = setTimeout(function closeWidget() {
- setIsSuccess(false)
- if (onClose) onClose()
- }, 2000)
- return function cleanup() {
- clearTimeout(timer)
- }
- }
- },
- [isSuccess, onClose]
- )
+ useEffect(
+ function handleSuccessAutoClose() {
+ if (isSuccess && onClose) {
+ const timer = setTimeout(function closeWidget() {
+ setIsSuccess(false)
+ onClose()
+ }, 2000)
+ return function cleanup() {
+ clearTimeout(timer)
+ }
+ }
+ },
+ [isSuccess, onClose]
+ )- <span className='text-xs text-muted-foreground font-normal'>
- Closing in 2 seconds...
- </span>
+ {onClose ? (
+ <span className='text-xs text-muted-foreground font-normal'>
+ Closing in 2 seconds...
+ </span>
+ ) : (
+ <span className='text-xs text-muted-foreground font-normal'>
+ You can close this window when you’re done.
+ </span>
+ )}Also applies to: 398-409
🤖 Prompt for AI Agents
In `@apps/desktop/src/features/drizzle-runner/components/lsp-demo-widget.tsx`
around lines 238 - 252, The auto-close effect handleSuccessAutoClose should only
perform the 2s auto-close and countdown when an onClose callback is provided;
update the useEffect so it checks that isSuccess && typeof onClose ===
"function" before setting the timer, and only call onClose and clear/set
IsSuccess inside that guarded branch (keep the cleanup to clear timer). Apply
the same guard to the other similar effect/logic that shows the "Closing in 2
seconds..." countdown and auto-clears success (the second effect around the
countdown), ensuring the message is only shown when onClose exists.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Remco <remcostoeten@hotmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Remco <remcostoeten@hotmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Remco <remcostoeten@hotmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Remco <remcostoeten@hotmail.com>
Summary by CodeRabbit
New Features
Bug Fixes
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.